﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Sofire.Data.XSql
{

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlNameNodeBase"/> 的集合。
    /// </summary>
    /// <typeparam name="TNameNode">集合项的数据类型。</typeparam>
    public abstract class XSqlNameNodeCollection<TNameNode> : ICollection<TNameNode>
        where TNameNode : class,IXSqlName
    {
        private readonly Dictionary<string, TNameNode> Inner;

        /// <summary>
        /// 获取指定 <paramref name="name"/> 的 <typeparamref name="TNameNode"/> 项。
        /// </summary>
        /// <param name="name">名称。</param>
        /// <returns>返回一个 <typeparamref name="TNameNode"/> 项，或一个 null 值。</returns>
        public TNameNode this[string name]
        {
            get
            {
                if(string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
                TNameNode value;
                lock(this.Inner)
                {
                    if(this.Inner.TryGetValue(name, out value))
                        return value;
                }
                return null;
            }
        }

        /// <summary>
        /// 指定可包含的初始元素数，初始化 <see cref="Sofire.Data.XSql.XSqlNameNodeCollection&lt;TNameNode&gt;"/> 的新实例。
        /// </summary>
        /// <param name="capacity">可包含的初始元素数。</param>
        public XSqlNameNodeCollection(int capacity)
        {
            this.Inner = new Dictionary<string, TNameNode>(capacity, StringComparer.CurrentCultureIgnoreCase);
        }

        /// <summary>
        /// 将一个 <typeparamref name="TNameNode"/> 添加或替换到集合中。
        /// </summary>
        /// <param name="node">一个 <typeparamref name="TNameNode"/> 项。</param>
        public void Add(TNameNode node)
        {
            if(node == null) throw new ArgumentNullException("node");
            if(string.IsNullOrEmpty(node.Name)) throw new ArgumentNullException("node.Name");
            lock(this.Inner)
            {
                this.Inner[node.Name] = node;
            }
        }

        /// <summary>
        /// 移除指定的 <typeparamref name="TNameNode"/> 项。
        /// </summary>
        /// <param name="node">一个 <typeparamref name="TNameNode"/> 项。</param>
        /// <returns>如果删除包含匹配的项，则返回 true，否则返回 false。</returns>
        public bool Remove(TNameNode node)
        {
            if(node == null) throw new ArgumentNullException("node");
            return this.Remove(node.Name);
        }

        /// <summary>
        /// 移除指定的名称的 <typeparamref name="TNameNode"/> 项。
        /// </summary>
        /// <param name="name">一个 <typeparamref name="TNameNode"/> 项的名称。</param>
        /// <returns>如果删除包含匹配的项，则返回 true，否则返回 false。</returns>
        public bool Remove(string name)
        {
            if(string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
            lock(this.Inner)
            {
                return this.Inner.Remove(name);
            }
        }

        /// <summary>
        /// 清空所有的 <typeparamref name="TNameNode"/> 项。
        /// </summary>
        public void Clear()
        {
            Inner.Clear();
        }

        /// <summary>
        /// 确定集合是否包含指定的 <typeparamref name="TNameNode"/> 项。
        /// </summary>
        /// <param name="node">一个 <typeparamref name="TNameNode"/> 项。</param>
        /// <returns>如果找到该项则返回 true，否则返回 false。</returns>
        public bool Contains(TNameNode node)
        {
            return this.Inner.ContainsValue(node);
        }
        /// <summary>
        /// 确定集合是否包含指定的 <typeparamref name="TNameNode"/> 项的名称。
        /// </summary>
        /// <param name="name">一个 <typeparamref name="TNameNode"/> 项的名称。</param>
        /// <returns>如果找到该项则返回 true，否则返回 false。</returns>
        public bool Contains(string name)
        {
            return this.Inner.ContainsKey(name);
        }

        /// <summary>
        /// 获取当前集合项的数目。
        /// </summary>
        public int Count
        {
            get { return this.Inner.Count; }
        }

        #region IEnumerable<XSqlTag> 成员

        IEnumerator<TNameNode> IEnumerable<TNameNode>.GetEnumerator()
        {
            return this.Inner.Values.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.Inner.Values.GetEnumerator();
        }

        #endregion

        void ICollection<TNameNode>.CopyTo(TNameNode[] array, int arrayIndex)
        {
            this.Inner.Values.CopyTo(array, arrayIndex);
        }

        bool ICollection<TNameNode>.IsReadOnly
        {
            get { return false; }
        }

    }

    /// <summary>
    /// 表示一个 <see cref="Sofire.Data.XSql.XSqlNode"/> 的集合。
    /// </summary>
    public class XSqlCollection : XSqlNameNodeCollection<IXSqlNode>, IXSqlNodeCollection
    {
        /// <summary>
        /// 指定可包含的初始元素数，初始化 <see cref="Sofire.Data.XSql.XSqlCollection"/> 的新实例。
        /// </summary>
        /// <param name="capacity">可包含的初始元素数。</param>
        public XSqlCollection(int capacity) : base(capacity) { }
    }
}
